﻿using System;
using System.Collections.Generic;
using Sandbox.Common.ObjectBuilders;
using Sandbox.Game;
using Sandbox.Game.Entities;
using Sandbox.Game.Entities.Character.Components;
using Sandbox.ModAPI;
using VRage.Game;
using VRage.Game.Components;
using VRage.Game.ModAPI;
using VRage.ModAPI;
using VRage.ObjectBuilders;
using VRageMath;

namespace Vicizlat.MultifloorCargoElevator
{
    [MyEntityComponentDescriptor(typeof(MyObjectBuilder_AdvancedDoor), false, "VCZ_Cargo_Elevator_Buttons")]
    public class MultifloorCargoElevatorButtons : MyGameLogicComponent
    {
        private IMyAdvancedDoor ElevatorButtons;
        private IMyPistonTop ElevatorTop;
        private IMyExtendedPistonBase Elevator_block;
        private bool[] LookingAtLightFloorChanged = new bool[9];
        private bool[] LookingAtLightFloor = new bool[9];
        private bool[] oldLookingAtLightFloor = new bool[9];
        private int FloorsCount;
        private int frame = -1;

        public override void Init(MyObjectBuilder_EntityBase objectBuilder)
        {
            NeedsUpdate |= MyEntityUpdateEnum.EACH_FRAME;
            ElevatorButtons = (IMyAdvancedDoor)Entity;
        }

        public override void Close() => NeedsUpdate = MyEntityUpdateEnum.NONE;

        public override void UpdateBeforeSimulation()
        {
            try
            {
                if (MyAPIGateway.Utilities.IsDedicated) return;
                if (ElevatorButtons.CubeGrid.Physics == null) return;
                if (frame++ == 59) frame = 0;

                if (ElevatorTop == null)
                {
                    List<IMySlimBlock> Neighbours = new List<IMySlimBlock>();
                    ElevatorButtons.SlimBlock.GetNeighbours(Neighbours);
                    foreach (var block in Neighbours)
                    {
                        if (block.BlockDefinition.Id.SubtypeName == "VCZ_Cargo_Elevator_Piston_Top")
                        {
                            ElevatorTop = block.FatBlock as IMyPistonTop;
                            Elevator_block = ElevatorTop.Piston as IMyExtendedPistonBase;
                        }
                    }
                }
                if (ElevatorTop == null || ElevatorTop.Closed)
                {
                    ElevatorButtons.CubeGrid.RazeBlock(ElevatorButtons.Position);
                    return;
                }
                (ElevatorButtons as MyAdvancedDoor).ChangeOwner(Elevator_block.OwnerId, MyOwnershipShareModeEnum.Faction);
                if (ElevatorButtons.ShowInTerminal) ElevatorButtons.ShowInTerminal = false;
                if (ElevatorButtons.ShowInToolbarConfig) ElevatorButtons.ShowInToolbarConfig = false;
                if (!Elevator_block.IsFunctional) return;
                if (frame == 59) FloorsCount = GetNumber("Floors Count");
                if (FloorsCount > 0) CheckAndUpdateButtonDisplays();
                if (ElevatorButtons.HasLocalPlayerAccess() && FloorsCount > 0) FindDesiredFloor();
            }
            catch (Exception e)
            {
                Logging.Instance.WriteLine("[ Error in 'MultifloorCargoElevatorButtons': " + e.StackTrace + " ]");
            }
        }

        private int GetNumber(string Name)
        {
            int ValuePosition = Elevator_block.CustomInfo.IndexOf(":", Elevator_block.CustomInfo.IndexOf(Name)) + 2;
            return Int32.Parse(Elevator_block.CustomInfo.Substring(ValuePosition, 1));
        }

        private void FindDesiredFloor()
        {
            if (MyAPIGateway.Gui.ActiveGamePlayScreen != null) return;
            if (MyAPIGateway.Session.Player.Character == null) return;
            IMyCharacter Player = MyAPIGateway.Session.Player.Character;
            for (int i = 0; i <= 8; i++) LookingAtLightFloor[i] = false;
            if (Player.Components.Get<MyCharacterDetectorComponent>()?.UseObject != null)
            {
                if (Player.Components.Get<MyCharacterDetectorComponent>().DetectedEntity != ElevatorButtons) return;
                var dummy = Player.Components.Get<MyCharacterDetectorComponent>().UseObject.Dummy as IMyModelDummy;
                bool UseDummy = MyAPIGateway.Input.IsGameControlReleased(MyControlsSpace.USE) || MyAPIGateway.Input.IsGameControlReleased(MyControlsSpace.PRIMARY_TOOL_ACTION);
                if (dummy.Name == "detector_advanceddoor_010" && UseDummy) Elevator_block.GameLogic.GetAs<MultifloorCargoElevator>().SendStopSignal();
                if (dummy.Name != "detector_advanceddoor_010")
                {
                    for (int i = 1; i <= FloorsCount; i++)
                    {
                        if (dummy.Name == "detector_advanceddoor_00" + i)
                        {
                            LookingAtLightFloor[i - 1] = true;
                            if (UseDummy) Elevator_block.GameLogic.GetAs<MultifloorCargoElevator>().SendToFloor(i);
                            break;
                        }
                    }
                }
            }
        }

        private void CheckAndUpdateButtonDisplays()
        {
            for (int i = 0; i <= 8; i++)
            {
                if (!LookingAtLightFloorChanged[i]) LookingAtLightFloorChanged[i] = LookingAtLightFloor[i] != oldLookingAtLightFloor[i];
                if (LookingAtLightFloorChanged[i])
                {
                    if (LookingAtLightFloor[i]) ElevatorTop.SetEmissivePartsForSubparts("LookingAtLightFloor" + (i + 1), Color.Orange, 1f);
                    else ElevatorTop.SetEmissivePartsForSubparts("LookingAtLightFloor" + (i + 1), Color.Black, 0f);
                    LookingAtLightFloorChanged[i] = false;
                }
                oldLookingAtLightFloor[i] = LookingAtLightFloor[i];
            }
        }
    }
}